/** 
* @Title: TraditionalThreadCommunication.java 
* @Package com.lh.threadtest.t4 
* @Description: TODO
* @author Liu 
* @date 2018年1月15日 下午9:28:23 
* @version V1.0 
*/
package com.lh.threadtest.t10;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/** 
* @ClassName: TraditionalThreadCommunication 
* @Description: java5条件阻塞Condition的应用
* 
* 老大循环100次，然后老二循环10次，接着老三循环20次，
* 又接着老大循环100次，老二又循环10次，老三又循环20次，
* 如此循环50次，请写出程序。
* 
* @author Liu
* @date 2018年1月15日 下午9:28:23 
*  
*/
public class ThreeConditionCommunication {
	public static void main(String[] args) {
		final Business business = new Business();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i = 1; i <= 50; i++){
					try {
						business.sub2(i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i = 1; i <= 50; i++){
					try {
						business.sub3(i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
		
		for(int i = 1; i <= 50; i++){
			try {
				business.main(i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
//不同点：	
//condition.business
//business
	
	//将具有类似功能的业务代码抽象到同一个类中
	//下面两个方法(sub/main)是互斥的，均是独立的一个同步模块，处于同一个互斥组(通过synchronized表明均属于同一个类，同一时刻只能有一个线程持有该锁)
	static class Business{
		Lock lock = new ReentrantLock();
		Condition condition = lock.newCondition();
		Condition condition2 = lock.newCondition();
		Condition condition3 = lock.newCondition();
		
		//主线程和子线程切换执行的一个标识
		int flag = 1;
		
		void sub3(int i) throws InterruptedException{
			lock.lock();
			try {
//				if(!flag){
				//循环和if功能相仿，但更加完备
				while(flag != 3){
					//使当前线程等待...
//					this.wait();
					condition3.await();
				}
				
				for(int j = 1; j <= 20; j++){
					System.out.println("sub3 thread sequence of "  + j + ", loop of " + i);
				}
				
				flag = 1;
				
				//唤醒其它正在等待的线程
//				this.notify();
				condition.signal();
			} finally {
				lock.unlock();
			}
		}
		
		void sub2(int i) throws InterruptedException{
			lock.lock();
			try {
//				if(!flag){
				//循环和if功能相仿，但更加完备
				while(flag != 2){
					//使当前线程等待...
//					this.wait();
					condition2.await();
				}
				
				for(int j = 1; j <= 10; j++){
					System.out.println("sub2 thread sequence of "  + j + ", loop of " + i);
				}
				
				flag = 3;
				
				//唤醒其它正在等待的线程
//				this.notify();
				condition3.signal();
			} finally {
				lock.unlock();
			}
		}
		
		void main(int i) throws InterruptedException{
			lock.lock();
			try {
//				if(flag){
				//循环和if功能相仿，但更加完备
				while(flag != 1){
					//使当前线程等待...
//					this.wait();
					condition.await();
				}
				
				for(int j = 1; j <= 100; j++){
					System.out.println("main thread sequence of "  + j + ", loop of " + i);
				}
				
				flag = 2;
				
				//唤醒其它正在等待的线程
//				this.notify();
				condition2.signal();
			} finally {
				lock.unlock();
			}
		}
	}
}
